import { _decorator, Component, Node, Enum } from 'cc';
import { BaseComponent } from '../main/script/Main';
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = EventManagerInstance
 * DateTime = Sat Apr 02 2022 12:30:40 GMT+0800 (中国标准时间)
 * Author = withtea
 * FileBasename = EventManagerInstance.ts
 * FileBasenameNoExtension = EventManagerInstance
 * URL = db://assets/scripts/UISystem/EventManagerInstance.ts
 * ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
 *
 */

export enum GameMsgType {
    GameResLoadEnd = 0,
    GameStart,
    GameEnd,
    GameResDownLoad,
    GetVideoListCallBack,
    ShareVideoCallBack,
    ShareCallBack,
    RewardADEnd,
    RewardADError,
    InterstADEndHanle,
    LoadConfigEnd,
    ReGame,
    Combob,
    EndGame,
    UpdataSkin,
    ChangeAssets,
    OpenChest,
    ShowGoldAdd,
    UpdataShop,
    LoadLanguageDataEnd,
}

@ccclass
export default class EventManagerInstance {
    private static instance: EventManagerInstance = null;
    private m_msg_dic: {};
    public static GetInstance(): EventManagerInstance {
        if (this.instance == null) {
            this.instance = new EventManagerInstance();
            this.instance.m_msg_dic = {};
        }
        return this.instance;
    }
    public Register(game_event_type: GameMsgType, cc: BaseComponent, action: Function) {
        this.clearSingleRegister(game_event_type);
        if (!this.m_msg_dic[game_event_type]) {
            this.m_msg_dic[game_event_type] = [];
        }
        if (this.isRegisterIn(game_event_type, cc, action)) {
            console.log('[EventManagerInstance] ' + game_event_type + ' is regied on ' + typeof cc);
            return;
        }
        this.m_msg_dic[game_event_type].push({
            cc: cc,
            action: action,
        });
    }
    public UnRegister(game_event_type: GameMsgType, cc: BaseComponent, action: Function) {
        if (this.m_msg_dic[game_event_type]) {
            for (let i = this.m_msg_dic[game_event_type].length - 1; i >= 0; i--) {
                if (this.m_msg_dic[game_event_type][i].cc == cc && this.m_msg_dic[game_event_type][i].action == action) {
                    this.m_msg_dic[game_event_type].splice(i, 1);
                    break;
                }
            }
        }
    }
    public Notify(game_event_type: GameMsgType, obj) {
        this.clearSingleRegister(game_event_type);
        if (this.m_msg_dic[game_event_type]) {
            for (let i = 0; i < this.m_msg_dic[game_event_type].length; i++) {
                if (this.m_msg_dic[game_event_type][i].cc.node != null) {
                    this.m_msg_dic[game_event_type][i].action.call(this.m_msg_dic[game_event_type][i].cc, obj);
                }
            }
        }
    }
    private clearSingleRegister(game_event_type: GameMsgType) {
        if (this.m_msg_dic[game_event_type]) {
            for (let i = this.m_msg_dic[game_event_type].length - 1; i >= 0; i--) {
                if (this.m_msg_dic[game_event_type][i].cc.node == null) {
                    this.m_msg_dic[game_event_type].splice(i, 1);
                }
            }
        }
    }
    private isRegisterIn(game_event_type: GameMsgType, cc: BaseComponent, action: Function) {
        if (this.m_msg_dic[game_event_type]) {
            for (let i = this.m_msg_dic[game_event_type].length - 1; i >= 0; i--) {
                if (this.m_msg_dic[game_event_type][i].cc == cc && this.m_msg_dic[game_event_type][i].action == action) {
                    return true;
                }
            }
        }
        return false;
    }
}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/zh/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/zh/scripting/decorator.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/zh/scripting/life-cycle-callbacks.html
 */
